package com.chen.seckill.service.impl;

import com.chen.seckill.dao.OrderMapper;
import com.chen.seckill.dao.SequenceMapper;
import com.chen.seckill.error.BusinessException;
import com.chen.seckill.error.EmBusinessError;
import com.chen.seckill.pojo.Order;
import com.chen.seckill.pojo.Sequence;
import com.chen.seckill.service.ItemService;
import com.chen.seckill.service.OrderService;
import com.chen.seckill.service.UserService;
import com.chen.seckill.service.bo.ItemBO;
import com.chen.seckill.service.bo.OrderBO;
import com.chen.seckill.service.bo.UserBO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import static org.springframework.transaction.annotation.Propagation.REQUIRES_NEW;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private ItemService itemService;

    @Autowired
    private UserService userService;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private SequenceMapper sequenceMapper;

    @Override
    @Transactional
    public OrderBO createOrder(Integer userId, Integer itemId, Integer promoId, Integer amount) throws BusinessException {
        // 1、校验下单状态。下单商品是否存在、用户是否合法、购物数量是否正确
        ItemBO itemBO = itemService.getItemById(itemId);
        if (itemBO == null) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "商品信息不存在");
        }

        UserBO userBO = userService.getUserById(userId);
        if (userBO == null) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "用户信息不存在");
        }

        if (amount < 0 || amount > 99) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "商品数量信息不正确");
        }

        // 校验活动信息
        if (promoId != null) {
            // 校验对应活动是否存在这个适用商品
            if (promoId.intValue() != itemBO.getPromoBO().getId()) {
                throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "活动信息不正确");
                // 校验活动是否正在进行中
            } else if (itemBO.getPromoBO().getStatus() != 2) {
                throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "活动还未开始");
            }
        }

        // 2、落单减库存
        boolean result = itemService.decreaseStock(itemId, amount);
        if (!result) {
            throw new BusinessException(EmBusinessError.STOCK_NOT_ENOUGH);
        }

        // 3、订单入库
        OrderBO orderBO = new OrderBO();
        orderBO.setUserId(userId);
        orderBO.setItemId(itemId);
        orderBO.setAmount(amount);
        orderBO.setPromoId(promoId);
        if (promoId != null) {
            orderBO.setItemPrice(itemBO.getPromoBO().getPromoItemPrice());
        } else {
            orderBO.setItemPrice(itemBO.getPrice());
        }
        orderBO.setOrderPrice(orderBO.getItemPrice().multiply(new BigDecimal(amount)));

        // 生成交易流水号
        orderBO.setId(generateOrderNo());
        Order order = convertFromOrderBO(orderBO);
        orderMapper.insertSelective(order);

        // 商品销量增加
        itemService.increaseSales(itemId, amount);

        // 4、返回前端
        return orderBO;
    }

    // 生成流水号
    @Transactional(propagation = REQUIRES_NEW)
    String generateOrderNo() {
        // 订单号有16位
        // 前8位是时间信息，年月日。方便日后数据庞大时，进行归档
        StringBuilder stringBuilder = new StringBuilder();
        LocalDateTime now = LocalDateTime.now();
        String nowStr = now.format(DateTimeFormatter.ISO_DATE).replace("-", "");
        stringBuilder.append(nowStr);

        // 中间6位为自增序列。
        // 获取当前Sequence
        int sequenceValue = 0;
        Sequence sequence = sequenceMapper.getSequenceByName("order_info");
        sequenceValue = sequence.getCurrentValue();
        // 更新下次使用的序列值
        sequence.setCurrentValue(sequence.getCurrentValue() + sequence.getStep());
        sequenceMapper.updateByPrimaryKeySelective(sequence);
        String sequenceStr = String.valueOf(sequenceValue);
        // 不足六位的拼接0操作
        for (int i = 0; i < 6 - sequenceStr.length(); i++) {
            stringBuilder.append(0);
        }
        stringBuilder.append(sequenceStr);

        // 最后两位为分库分表位。订单的水平拆分。先写死
        stringBuilder.append("00");
        return stringBuilder.toString();
    }

    // 从OrderBO转化为Order
    private Order convertFromOrderBO(OrderBO orderBO) {
        if (orderBO == null) {
            return null;
        }
        Order order = new Order();
        BeanUtils.copyProperties(orderBO, order);
        // BO中是BigDecimal，DO中是double，需要进行转化，否则BeanUtils.copyProperties不能完全成功赋值
        order.setItemPrice(orderBO.getItemPrice().doubleValue());
        order.setOrderPrice(orderBO.getOrderPrice().doubleValue());
        return order;
    }
}
